import { AutoComplete, Button } from "antd";
import { useCallback, useEffect, useRef, useState } from "react";
import style from "./LyAutoComplete.module.css";
import React from "react";

interface Columns {
  title: string; //列标题
  dataIndex: string; // 列字段名
  key: string; // 列key
  width?: number; //列宽度
  align?: "left" | "right" | "center" | string; //列对齐方式
  render?: (text: string, record: any) => any; //自定义渲染
  headAlign?: "left" | "right" | "center" | string; //列标题对齐方式
}

interface Props {
  options: any[]; // 搜索数据
  debounceTime?: number; // 防抖时间
  suffix?: any; // 后缀
  placeholder?: string; // 提示
  columns: Columns[]; // 定义表格字段
  searchOptions?: (value: string) => any; // 输入时异步调用，
  value?: string; // 默认值
  valueKey: string; // 选择后的值的key
  onSuffixClick?: () => any; //后缀点击事件
  isDisabledSuffix?: boolean; //是否禁用后缀
  onChange?: (value: string, obj: any) => any; //值改变时调用,值为valueKey字段
  key?: string;
  isNotFocus?: boolean; //是否不聚焦
  allowClear?: boolean;
  isNotFocusSuffix?: any;
  minWidth?: string;
  antdOptions?: any;
  maxLength?: number;
}

const LyAutoComplete = ({
  isNotFocusSuffix,
  options = [],
  debounceTime,
  suffix,
  placeholder,
  columns,
  value = undefined,
  valueKey,
  searchOptions = () => undefined,
  onChange = undefined,
  onSuffixClick = undefined,
  key = "id",
  isDisabledSuffix = false,
  isNotFocus = false,
  minWidth = undefined,
  antdOptions = {},
  maxLength = undefined,
}: Props) => {
  // 是否展开
  const [open, setOpen] = useState(false);
  // 定时器
  const [timer, setTimer] = useState(null);
  // 组件显示的值
  const [valueCom, setValueCom] = useState(value);

  // const [valueCom, setValueCom] = useState(value);

  // 是否获取焦点
  const [isFocus, setIsFocus] = useState(false);

  const autoCompleteRef = useRef(null);

  useEffect(() => {
    setValueCom(value);
  }, [value]);

  // 第一行表头
  const unshiftRow = useCallback(() => {
    const ColumnsCol = () => {
      return columns.map((col) => {
        const { headAlign = "center" } = col;
        return (
          <div
            style={{
              width: col.width || "auto",
              textAlign: headAlign,
              fontWeight: 900,
            }}
            key={col.key}
          >
            {col.title}
          </div>
        );
      });
    };

    const ColumnsRow = (
      <div className={style.div_label_row}>
        <ColumnsCol />
      </div>
    );

    return {
      value: undefined,
      label: ColumnsRow,
    };
  }, [columns]);

  // 生成表格
  const generateOptionsTable = useCallback(
    (options: any) => {
      const newOptions = options.map((item: any) => {
        const LabelCol = () => {
          return columns.map((col) => {
            const { align = "left" } = col;
            // const align = col?.align;
            let renderContent = item[col?.dataIndex];
            if (!Reflect.has(col, "key")) {
              Promise.reject(new Error("key属性不能为空"));
            }
            if (Reflect.has(col, "render")) {
              renderContent = col.render(item[col?.dataIndex], item);
            }
            return (
              <div
                style={{ width: col?.width || "auto", textAlign: align }}
                key={col.key}
              >
                {renderContent}
              </div>
            );
          });
        };
        const labelRow = (
          <>
            <div className={style.div_label_row}>
              <LabelCol key={item.id} />
            </div>
          </>
        );

        return {
          value: item[key],
          label: labelRow,
          data: item,
        };
      });

      return newOptions;
    },
    [columns, key]
  );

  const [optionsData, setOptionsData] = useState([
    unshiftRow(),
    ...generateOptionsTable(options),
  ]);

  useEffect(() => {
    if (options?.length && isFocus) {
      setOpen(true);
    } else {
      setOpen(false);
    }
    if (options?.length === 0) {
      setOptionsData([]);
    } else {
      setOptionsData([unshiftRow(), ...generateOptionsTable(options)]);
    }
  }, [generateOptionsTable, isFocus, options, unshiftRow, value]);

  const onFocus = () => {
    setIsFocus(true);
    autoCompleteRef.current.focus();
    if (options?.length) {
      setOpen(true);
    }
  };

  // 失去焦点
  const onBlur = () => {
    setIsFocus(false);
    setOpen(false);
  };

  // 选择
  const onSelect = (value: any, obj: any) => {
    if (onChange) {
      onChange(obj.data[valueKey], obj.data);
    }
    // setValueCom(value);
    setOpen(false);
    autoCompleteRef.current.blur();
  };

  const suffixClick = () => {
    if (onSuffixClick) {
      onSuffixClick();
    }
  };

  // 搜索时调用
  const onSearch = useCallback(
    (value) => {
      // 是否设置最大长度
      if (maxLength) {
        // 限制输入长度
        const isMaxLength = value.length > maxLength;
        if (isMaxLength) return;
      }

      setValueCom(value);
      // 触发onChange事件
      if (onChange) {
        onChange(value, null);
      }

      if (timer) {
        clearTimeout(timer);
      }
      const timeObj = setTimeout(() => {
        searchOptions(value);
      }, debounceTime);
      setTimer(timeObj);
    },
    [debounceTime, onChange, searchOptions, timer]
  );

  // 没有数据时显示的内容
  const NotFoundContent = () => {
    return (
      <div className={style.div_notFoundContent}>
        <div>暂无数据</div>
      </div>
    );
  };

  return (
    <>
      <div className={style.div_autoComplete}>
        {isNotFocus && (
          <div onClick={onFocus} className={style.shadeBox}>
            {valueCom && isNotFocusSuffix && (
              // <CloseOutlined
              //   onClick={(e) => {
              //     e.stopPropagation();
              //     setValueCom(undefined);
              //   }}
              //   className={style.clearIcon}
              // />
              <span
                className={style.clearIcon}
                // onClick={(e) => {
                //   e.stopPropagation();
                //   setValueCom(undefined);
                // }}
              >
                {isNotFocusSuffix}
              </span>
            )}
          </div>
        )}
        <AutoComplete
          {...antdOptions}
          style={{ minWidth: minWidth }}
          className={isNotFocus ? style.isNotFocus : ""}
          ref={autoCompleteRef}
          // value={value ? value : undefined}
          value={valueCom}
          popupMatchSelectWidth={false}
          open={open}
          placeholder={placeholder}
          defaultOpen={false}
          options={optionsData}
          onFocus={onFocus}
          onSearch={onSearch}
          onBlur={onBlur}
          onSelect={onSelect}
          notFoundContent={NotFoundContent()}
        ></AutoComplete>
        <Button
          disabled={isDisabledSuffix}
          type="link"
          onClick={suffixClick}
          className={style.btn_suffix}
        >
          <span className={style.btn_span_suffix}>{suffix}</span>
        </Button>
      </div>
    </>
  );
};
export default React.memo(LyAutoComplete);
